﻿using System.Collections.Generic;

namespace SHomeWorkshop.LunarConcept
{
    /// <summary>
    /// 纸张信息。由物理纸张尺寸转化为WPF纸张尺寸（96DPI下）。
    /// </summary>
    public class PaperInfo
    {
        /// <summary>
        /// [构造方法]
        /// </summary>
        /// <param name="name">纸张类型名称。例如：A4</param>
        /// <param name="shortSideWPFUnit">会自动取“shortSideWPFUnit”和“longSideWPFUnit”这两个参数中较小的值来初始化“ShortSideWPFUnit”属性。</param>
        /// <param name="longSideWPFUnit">会自动取“shortSideWPFUnit”和“longSideWPFUnit”这两个参数中较大的值来初始化“LongSideWPFUnit”属性。</param>
        /// <param name="shortSidePixcelCount">与前两个参数类似，后两个参数也会自动比较大小。</param>
        /// <param name="longSidePixcelCount">与前两个参数类似，后两个参数也会自动比较大小。</param>
        public PaperInfo(string name, double shortSideWPFUnit, double longSideWPFUnit,
            int shortSidePixcelCount, int longSidePixcelCount)
        {
            paperTypeName = name;

            if (shortSideWPFUnit < longSideWPFUnit)
            {
                this.shortSideWPFUnit = shortSideWPFUnit;
                this.longSideWPFUnit = longSideWPFUnit;
            }
            else
            {
                this.shortSideWPFUnit = longSideWPFUnit;
                this.longSideWPFUnit = shortSideWPFUnit;
            }

            if (shortSidePixcelCount < longSidePixcelCount)
            {
                this.shortSidePixcelCount = shortSidePixcelCount;
                this.longSidePixcelCount = longSidePixcelCount;
            }
            else
            {
                this.shortSidePixcelCount = longSidePixcelCount;
                this.longSidePixcelCount = shortSidePixcelCount;
            }
        }

        private static List<PaperInfo> paperInfos = new List<PaperInfo>();

        static PaperInfo()
        {
            //幻灯片尺寸（适合1024×768的显示器，这是考虑到当前使用的投影仪）
            //paperInfos.Add(new PaperInfo("Slide", 600, 940, 1950, 2938));
            //手头所有投影仪都是640*480，因此，修改之。另，着手做“扩展到投影屏幕功能”。2013年1月1日
            paperInfos.Add(new PaperInfo("Slide640_480", 480, 640, 1560, 2080));
            paperInfos.Add(new PaperInfo("Slide800_600", 600, 800, 1950, 2600));
            paperInfos.Add(new PaperInfo("Slide1024_768", 768, 1024, 2496, 3328));

            paperInfos.Add(new PaperInfo("Slide480_640", 480, 640, 1560, 2080));
            paperInfos.Add(new PaperInfo("Slide600_800", 600, 800, 1950, 2600));
            paperInfos.Add(new PaperInfo("Slide768_1024", 768, 1024, 2496, 3328));

            paperInfos.Add(new PaperInfo("Slide640*480", 480, 640, 1560, 2080));
            paperInfos.Add(new PaperInfo("Slide800*600", 600, 800, 1950, 2600));
            paperInfos.Add(new PaperInfo("Slide1024*768", 768, 1024, 2496, 3328));

            paperInfos.Add(new PaperInfo("Slide480*640", 480, 640, 1560, 2080));
            paperInfos.Add(new PaperInfo("Slide600*800", 600, 800, 1950, 2600));
            paperInfos.Add(new PaperInfo("Slide768*1024", 768, 1024, 2496, 3328));

            paperInfos.Add(new PaperInfo("A0", 4493.9, 3178.6, 14043, 9933));
            paperInfos.Add(new PaperInfo("A1", 3178.6, 2245.0, 9933, 7015));
            paperInfos.Add(new PaperInfo("A2", 2245.0, 1587.4, 7015, 4960));
            paperInfos.Add(new PaperInfo("A3", 1587.4, 1122.5, 4960, 3507));
            paperInfos.Add(new PaperInfo("A4", 793.7, 1122.5, 2480, 3507));
            paperInfos.Add(new PaperInfo("A5", 559.4, 793.7, 1748, 2480));
            paperInfos.Add(new PaperInfo("A6", 396.9, 559.4, 1240, 1748));
            paperInfos.Add(new PaperInfo("A7", 279.7, 396.9, 874, 1240));
            paperInfos.Add(new PaperInfo("A8", 196.5, 279.7, 614, 874));
            paperInfos.Add(new PaperInfo("A9", 139.8, 196.5, 437, 614));
            paperInfos.Add(new PaperInfo("A10", 98.3, 139.8, 307, 437));

            paperInfos.Add(new PaperInfo("B0", 3779.5, 5344.3, 11811, 16700));
            paperInfos.Add(new PaperInfo("B1", 2672.1, 3779.5, 8350, 11811));
            paperInfos.Add(new PaperInfo("B2", 1889.8, 2672.1, 5905, 8350));
            paperInfos.Add(new PaperInfo("B3", 1334.2, 1889.8, 4169, 5905));
            paperInfos.Add(new PaperInfo("B4", 944.9, 1334.2, 2952, 4169));
            paperInfos.Add(new PaperInfo("B5", 665.2, 944.9, 2078, 2952));
            paperInfos.Add(new PaperInfo("B6", 472.4, 665.2, 1476, 2078));
            paperInfos.Add(new PaperInfo("B7", 332.6, 472.4, 1039, 1476));
            paperInfos.Add(new PaperInfo("B8", 234.3, 332.6, 732, 1039));
            paperInfos.Add(new PaperInfo("B9", 166.3, 234.3, 519, 732));
            paperInfos.Add(new PaperInfo("B10", 117.2, 166.3, 366, 519));

            //正度开法
            paperInfos.Add(new PaperInfo("1K", 2781.7, 3930.7, 8693, 12284));
            paperInfos.Add(new PaperInfo("2K", 1965.4, 2781.7, 6142, 8693));
            paperInfos.Add(new PaperInfo("4K", 1390.9, 1965.4, 4347, 6142));
            paperInfos.Add(new PaperInfo("8K", 982.7, 1390.9, 3071, 4347));
            paperInfos.Add(new PaperInfo("16K", 695.4, 982.7, 2173, 3071));
            paperInfos.Add(new PaperInfo("32K", 491.3, 695.4, 1535, 2173));

            //常见手机屏幕分辨率
            paperInfos.Add(new PaperInfo("xxhdpi", 1920, 1080, 6240, 3510));
            paperInfos.Add(new PaperInfo("xhdpi", 1280, 720, 4160, 2340));
            paperInfos.Add(new PaperInfo("hdpi", 480, 800, 1560, 2600));
            paperInfos.Add(new PaperInfo("mhdpi", 480, 320, 1560, 1040));
            paperInfos.Add(new PaperInfo("lhdpi", 320, 240, 1040, 780));
        }

        /// <summary>
        /// 按纸张类型名称返回纸型的PaperInfo。
        /// 支持的纸型包括：A0~A10,B0~B10,
        /// 以及一个自定义的适合（640*480）屏幕的幻灯片尺寸（Slide）。
        /// 如果是不支持的类型，会返回null。
        /// </summary>
        /// <param name="paperName">纸型名称。例如：“A4”(不含引号）。</param>
        /// <returns>返回PaperInfo实例。如果传入的参数是不支持的纸型，会返回null。</returns>
        public static PaperInfo GetPaperInfo(string paperName)
        {
            if (paperName == null) return null;

            paperName = paperName.Replace("╳", "*");
            paperName = paperName.Replace("＊", "*");
            paperName = paperName.Replace("×", "*");
            paperName = paperName.Replace("/", "*");
            paperName = paperName.Replace(" ", "*");

            if (paperName.ToLower() == "presentation" || paperName.ToLower() == "slide")//保持与改名前的文档兼容。
            {
                paperName = "slide640*480";
            }

            foreach (PaperInfo pi in paperInfos)
            {
                if (pi.PaperTypeName.ToLower() == paperName.ToLower()) return pi;
            }

            return null;
        }

        #region 参考资料
        //如何计算WpfPixcelUnit（Wpf与设备无关单位）值。
        //Pixcel=毫米数*（像素/毫米）
        //WpfDPI值是96。
        //WpfPixcelUnit=Pixcel*WpfDPI/ImageDPI
        //于是：
        //WpfPixcelUnit=毫米数*（像素/毫米）*WpfDPI/ImageDPI
        //对于300DPI的图片来说：1毫米＝11.811024003348像素。
        //因此：
        //WpfPixcelUnit=毫米数*11.811024003348*WpfDPI/ImageDPI
        //最终结果：
        //WpfPixcelUnit=毫米数*11.811024003348*96/300;
        //也就是：
        //WpfPixcelUnit=毫米数*3.77952768107136 
        #endregion

        private static readonly double ratioValueFromMmToWpfPixcelUnits = 3.77952768107136;

        /// <summary>
        /// [静态只读]毫米到WPF“与设备无关单位”的转换率参数。
        /// </summary>
        public static double RatioValueFromMmToWpfPixcelUnits
        {
            get { return PaperInfo.ratioValueFromMmToWpfPixcelUnits; }
        }

        public static bool IsValidatePaperName(string paperName)
        {
            if (string.IsNullOrEmpty(paperName)) return false;

            paperName = paperName.ToLower();

            paperName = paperName.Replace("╳", "*");
            paperName = paperName.Replace("＊", "*");
            paperName = paperName.Replace("×", "*");
            paperName = paperName.Replace("/", "*");
            paperName = paperName.Replace(" ", "*");

            switch (paperName)//经过小写处理
            {
                case "presentation"://保持与旧文档兼容
                case "slide":
                case "slide800*600":
                case "slide600*800":
                case "slide640*480":
                case "slide480*640":
                case "slide1024*768":
                case "slide768*1024":
                case "slide800_600":
                case "slide600_800":
                case "slide640_480":
                case "slide480_640":
                case "slide1024_768":
                case "slide768_1024":
                case "a0":
                case "a1":
                case "a2":
                case "a3":
                case "a4":
                case "a5":
                case "a6":
                case "a7":
                case "a8":
                case "a9":
                case "a10":

                case "b0":
                case "b1":
                case "b2":
                case "b3":
                case "b4":
                case "b5":
                case "b6":
                case "b7":
                case "b8":
                case "b9":
                case "b10":

                case "1k":
                case "2k":
                case "4k":
                case "8k":
                case "16k":
                case "32k":
                case "xxhdpi":
                case "xhdpi":
                case "hdpi":
                case "mhdpi":
                case "lhdpi":
                    return true;
            }

            return false;
        }

        private string paperTypeName = "A4";

        /// <summary>
        /// [只读]纸型名称。
        /// </summary>
        public string PaperTypeName
        {
            get { return paperTypeName; }
        }

        private double shortSideWPFUnit = 793.7;

        /// <summary>
        /// [只读]纸型的短边转换成WPF“与设备无关单位”的值。
        /// </summary>
        public double ShortSideWPFUnit
        {
            get { return shortSideWPFUnit; }
        }

        /// <summary>
        /// [只读]纸型的长边转换成WPF“与设备无关单位”的值。
        /// </summary>
        private double longSideWPFUnit = 1122.5;

        public double LongSideWPFUnit
        {
            get { return longSideWPFUnit; }
        }

        private int shortSidePixcelCount = 2480;

        /// <summary>
        /// [只读]纸型的短边转换成像素单位的值。
        /// </summary>
        public int ShortSidePixcelCount
        {
            get { return shortSidePixcelCount; }
        }

        private int longSidePixcelCount = 3507;

        /// <summary>
        /// [只读]纸型的长边转换成像素单位的值。
        /// </summary>
        public int LongSidePixcelCount
        {
            get { return longSidePixcelCount; }
        }
    }
}
